package net.suncaper.psychological.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JDBC工具类
 */
public class JDBCUtils {
    /**
     * 数据源
     */
    private static DataSource dataSource;

    /**
     * 同一个线程共享的数据库连接
     */
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

    /**
     * 初始化数据源及数据库连接池
     */
    static {
        try {
            // 创建一个Properties的对象
            Properties properties = new Properties();
            // 加载配置文件
            InputStream inputStream = JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties");
            properties.load(inputStream);

            // 转换属性名称以适配Druid连接池
            Properties druidProperties = new Properties();
            druidProperties.setProperty("driverClassName", properties.getProperty("db.driver"));
            druidProperties.setProperty("url", properties.getProperty("db.url"));
            druidProperties.setProperty("username", properties.getProperty("db.user"));
            druidProperties.setProperty("password", properties.getProperty("db.password"));
            
            // 添加默认的连接池配置
            druidProperties.setProperty("initialSize", "5");
            druidProperties.setProperty("maxActive", "20");
            druidProperties.setProperty("maxWait", "60000");
            druidProperties.setProperty("timeBetweenEvictionRunsMillis", "60000");
            druidProperties.setProperty("minEvictableIdleTimeMillis", "300000");
            druidProperties.setProperty("validationQuery", "SELECT 1");
            druidProperties.setProperty("testWhileIdle", "true");
            druidProperties.setProperty("testOnBorrow", "false");
            druidProperties.setProperty("testOnReturn", "false");

            // 创建DataSource
            dataSource = DruidDataSourceFactory.createDataSource(druidProperties);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取数据库连接
     */
    public static Connection getConnection() {
        // 先从ThreadLocal获取数据库连接
        Connection connection = threadLocal.get();

        // 如果从ThreadLocal没有获取到connection，就从连接池获取
        if (connection == null) {
            try {
                connection = dataSource.getConnection();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }

        return connection;
    }

    /**
     * 释放数据库连接
     */
    public static void close() {
        // 先从ThreadLocal获取数据库连接
        Connection connection = threadLocal.get();

        // 获取的connection不为null才进行释放
        if (connection != null) {
            // 从ThreadLocal移除
            threadLocal.remove();
            try {
                // 释放连接（这里是回收到Druid连接池）
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
